<template>
  <div :class="$style.myMap">
    <div ref="mapRef" style="width: 100%; height: 100%" />
    <div :class="$style['langed']">
      <div
        v-for="(item, key) in langed"
        :key="key"
        :class="$style['content']"
        @click="handleLegend(key as string)"
      >
        <div
          :class="$style['circle']"
          :style="[
            item.selected
              ? { backgroundColor: item.color }
              : { backgroundColor: '#929292' },
          ]"
        ></div>
        <div>{{ item.text }}</div>
      </div>
    </div>
    <div v-if="mapUrlQueueSize !== 1" :class="$style['backMapBtn']">
      <span :class="$style['backMapLabel']" @click="backTopMapArea">
        返回上一级
      </span>
    </div>
  </div>
</template>

<script setup lang="ts">
import { computed, onMounted, ref, inject } from 'vue';
// import * as echarts from 'echarts';
import { gcj02tobd09, getGeoData, mockData, nowSize, ThemeData } from './data';
import { useRouter } from 'vue-router';

/** @description 未开始项目 */
const NOT_BEGIN = 'NOT_STARTED';
/** @description 进行中项目 */
const RUNNING = 'CONSTRUCTION';
/** @description 已完成项目  */
const FINISH = 'COMPLETED';
// 地图的级别
/** @description 地图的级别：全国 */
const LEVEL_TYPE_COUNTRY = 'CHINA';
/** @description 地图的级别：省 */
const LEVEL_TYPE_PROVINCE = 'PROVINCE';
/** @description 地图的级别：市 */
const LEVEL_TYPE_CITY = 'CITY';
/** @description 缓存项目 */
const projectListMap = new Map();
// 颜色变量
/** @description 未开始项目 */
const Color_NotBegin = '#4196FF';
/** @description 进行中项目 */
const Color_Running = '#FFCC36';
/** @description 已完成项目 */
const Color_Finish = '#00C46D';

type mapUrlQueueType = {
  level: string;
  adcode: string;
  value: string;
};
const selectLanged = ref('');
const handleLegend = (key: string) => {
  selectLanged.value = key;
  langed.value[key].selected = !langed.value[key].selected;
  const option = myChart.value.getOption();
  const obj = {
    notBegin: 0,
    running: 1,
    finish: 2,
  };
  const idx: number =
    obj[key as keyof { notBegin: string; running: string; finish: string }];
  option.series[idx].data = langed.value[key].selected
    ? projectObject.value[(key + 'List') as keyof ProjectObj]
    : [];
  myChart.value.setOption(option);
};
const mapRef = ref();
const langed = ref<{
  [key: string]: { text: string; color: string; selected: boolean };
}>({
  notBegin: {
    text: '未开始',
    color: Color_NotBegin,
    selected: true,
  },
  running: {
    text: '进行中',
    color: Color_Running,
    selected: true,
  },
  finish: {
    text: '已竣工',
    color: Color_Finish,
    selected: true,
  },
});
const clickDiff = ref(false);
const backTopMapArea = () => {
  if (clickDiff.value) return false;
  mapUrlQueue.value.pop();
  if (mapUrlQueueSize.value) {
    const adress = mapUrlQueue.value[mapUrlQueueSize.value - 1].value;
    emits('dbAdress', adress);
  }
  type.value = lastMapUrlQueueItem.value.level;
  switch (type.value) {
    case LEVEL_TYPE_COUNTRY:
      countryMapName.value = 'china';
      provineMapName.value = '';
      cityMapName.value = '';
      break;
    case LEVEL_TYPE_PROVINCE:
      provineMapName.value = lastMapUrlQueueItem.value.value;
      cityMapName.value = '';
      break;
    case LEVEL_TYPE_CITY:
      cityMapName.value = lastMapUrlQueueItem.value.value;
      break;
  }
  initChart();
  clickDiff.value = true;
  setTimeout(() => {
    clickDiff.value = false;
  }, 500);
};
const mapUrlQueue = ref<mapUrlQueueType[]>([]);
const mapUrlQueueSize = computed(() => {
  return mapUrlQueue.value.length;
});

onMounted(() => {
  init();
});
const type = ref(LEVEL_TYPE_COUNTRY);
const init = (): void => {
  if (mapUrlQueue.value.length === 0) {
    mapUrlQueue.value.push({
      level: type.value,
      adcode: '100000',
      value: '全国',
    });
  } else {
    type.value = lastMapUrlQueueItem.value.level;
  }
  initChart();
};
const lastMapUrlQueueItem = computed(() => {
  return mapUrlQueue.value.at(-1) as mapUrlQueueType;
});
const myChart = ref();
type ProjectObj = {
  notBeginList: any[];
  runningList: any[];
  finishList: any[];
};
const projectObject = ref<ProjectObj>({} as ProjectObj);
const echarts = inject<any>('$echarts');
const initChart = async () => {
  if (!myChart.value) {
    const chart: HTMLElement = mapRef.value;
    myChart.value = echarts.init(chart, {}, { devicePixelRatio: 2 });
  }
  projectObject.value = formatProjectData(mockData);
  projectListMap.set(getMapRegisterName(type.value), projectObject.value);
  await registerMap();
  const option = defaultOptions(selected.value);
  myChart.value.setOption(option, true);
  // await chartResize(false, selected.value);
  // 监听事件
  handleEchartsEventListener();
};
const formatProjectData = (data: any[]) => {
  const notBeginList: any[] = []; // 未开始项目-NOT_BEGIN
  const runningList: any[] = []; // 已退场项目-RUNNING
  const finishList: any[] = []; // 已进场项目-FINISH
  if (Array.isArray(data)) {
    data.forEach(v => {
      const { lng, lat } = gcj02tobd09(v.longitude, v.latitude);
      if (v.projectStatus === RUNNING) {
        runningList.push({
          ...v,
          value: [lng, lat],
        });
      }
      if (v.projectStatus === FINISH) {
        finishList.push({
          ...v,
          value: [lng, lat],
        });
      }
      if (v.projectStatus === NOT_BEGIN) {
        notBeginList.push({
          ...v,
          value: [lng, lat],
        });
      }
    });
  }

  return {
    notBeginList,
    runningList,
    finishList,
  };
};

const countryMapName = ref('china');
const provineMapName = ref('');
const cityMapName = ref('');
const getMapRegisterName = (type: string): string => {
  let typeName = '';
  switch (type) {
    case LEVEL_TYPE_COUNTRY:
      typeName = countryMapName.value;
      break;
    case LEVEL_TYPE_PROVINCE:
      typeName = provineMapName.value;
      break;
    case LEVEL_TYPE_CITY:
      typeName = cityMapName.value;
      break;
    default:
      typeName = countryMapName.value;
  }
  return typeName;
};

const selected = ref<string>('china');
const registerMap = async () => {
  try {
    switch (type.value) {
      case LEVEL_TYPE_COUNTRY:
        selected.value = countryMapName.value;
        break;
      case LEVEL_TYPE_PROVINCE:
        selected.value = provineMapName.value;
        break;
      case LEVEL_TYPE_CITY:
        selected.value = cityMapName.value;
        break;
    }

    let areaJson = '';
    areaJson = await getGeoData(lastMapUrlQueueItem.value.adcode);
    echarts.registerMap(selected.value, areaJson);
  } catch (error) {
    return 'china';
  }
};

const defaultOptions = (geo: string): any => {
  const themeMode = ThemeData.tint;
  const themeColor = ThemeData.purple;
  const commonToolTipStyle = {
    backgroundColor: themeMode.mainBg,
    trigger: 'item',
    textStyle: {
      color: themeMode.font,
      fontSize: nowSize(14),
    },
    extraCssText: 'border-radius:5px;border-color: var(--border)',
    padding: [nowSize(10)],
  };
  const commonObj = {
    symbol: 'circle',
    type: 'scatter', // series图表类型 effectScatter动画
    coordinateSystem: 'geo',
    data: [],
    tooltip: {
      ...commonToolTipStyle,
      trigger: 'item',
      formatter: formatSeriesObject,
    },
  };
  const { notBeginList, runningList, finishList } = projectObject.value;
  return {
    tooltip: {
      ...commonToolTipStyle,
      formatter: getFormatter,
    },
    geo: {
      map: geo,
      roam: true,
      zoom: geo === 'china' ? 1.7 : 1,
      top: geo === 'china' ? '30%' : '5%',
      // left: '20%',
      label: {
        color: themeMode.font,
      },
      itemStyle: {
        borderColor: themeColor.primary50,
        areaColor: themeColor.primary_fade_30,
      },
      scaleLimit: {
        min: 1,
        max: 5,
      },
      emphasis: {
        itemStyle: {
          areaColor: themeColor.primary60,
          shadowColor: themeColor.primary50,
        },
        label: {
          color: themeMode.font,
        },
      },
      select: {
        itemStyle: {
          areaColor: themeColor.primary60,
        },
        label: {
          color: themeMode.font,
        },
      },
    },
    series: [
      Object.assign({}, commonObj, {
        data: notBeginList,
        symbolSize: nowSize(8),
        z: 11,
        itemStyle: {
          color: Color_NotBegin,
        },
      }),
      Object.assign({}, commonObj, {
        data: runningList,
        symbolSize: nowSize(8),
        z: 10,
        itemStyle: {
          color: Color_Running,
        },
      }),
      Object.assign({}, commonObj, {
        data: finishList,
        symbolSize: nowSize(10),
        z: 14,
        itemStyle: {
          color: Color_Finish,
        },
      }),
      {
        name: '楼栋分布', // 浮动框的标题
        type: 'map',
        map: 'china',
        geoIndex: 0,
        data: [],
      },
    ],
  };
};
const formatSeriesObject = (params: { data: any }): string => {
  const data = params.data;
  const projectName = data.projectName;
  const address = data.detailAddress;
  const alarmCount = data.alarmCount;
  let str = `<div class="toolTipTitle projectTitle">${projectName}</div>`;
  str += `
        <div class=toolTipBuild>
          <div class=labelTip>项目地址</div>
          <div class="valueTip projectTip">
          	<div class="address">
          		${address}
          	</div>
					</div>
        </div>
        <div class=toolTipBuild>
          <div class=labelTip>当天警报</div>
          <div class=valueTip>${alarmCount}</div>
        </div>`;
  return `
      <div class="screenProjectBox">
        ${str}
      </div>
    `;
};

const getFormatter = (params: { name: string }): string => {
  const name = params.name;
  const mapAddress: any = {
    ['江苏省']: {
      deviceCount: 19,
      projectCount: 2,
      todayAlarm: 0,
      regionName: '江苏省',
    },
    ['北京市']: {
      deviceCount: 923,
      projectCount: 223,
      todayAlarm: 10,
      regionName: '北京市',
    },
  };
  const data = mapAddress[name];
  const result = {
    p: data?.projectCount || 0,
    d: data?.deviceCount || 0,
    w: data?.todayAlarm || 0,
  };
  let str = `<div class="toolTipTitle">${name}</div>`;
  str += `
        <div class=toolTipBuild>
          <div class=labelTip>项目总数</div>
          <div class=valueTip>${result.p}</div>
        </div>
        <div class=toolTipBuild>
          <div class=labelTip>设备总数</div>
          <div class=valueTip>${result.d}</div>
        </div>
        <div class=toolTipBuild>
          <div class=labelTip>当天警报</div>
          <div class=valueTip>${result.w}</div>
        </div>`;
  return `
      <div class="screenAreaBox">
        ${str}
      </div>
    `;
};
const router = useRouter();
const emits = defineEmits<{
  (e: 'dbAdress', name: string): void;
}>();
// 监听事件
const handleEchartsEventListener = () => {
  myChart.value.off('click'); // 点击事件之前，要释放之前的点击事件
  myChart.value.off('dblclick');
  // 单击事件
  myChart.value.on('click', (params: { data: { pkId: string } }) => {
    // 跳转到项目去
    if (params.data && params.data.pkId) {
      const rt = router.resolve({
        path: `/project/${params.data.pkId}`,
      });
      window.open(rt.href, '_blank');
    }
  });
  // 双击事件切换地图
  myChart.value.on('dblclick', async (params: { name: string }) => {
    await handleMapUrl(params);
    await initChart();
    emits('dbAdress', params.name);
  });
};
/**
 * @description 下钻地图队列
 * @param params
 * @returns {Promise<boolean>}
 */
const handleMapUrl = async (params: {
  name: string;
}): Promise<boolean | undefined> => {
  if (!params.name) {
    return false;
  }
  // 通过地图名称获取 adcode
  // const { adcode, name } = await getAdcodeByArea(params.name);
  const adcode = '440000';
  const name = '广东省';
  if (type.value === LEVEL_TYPE_COUNTRY) {
    const provinceName = formatProvinceName('广东省');
    type.value = LEVEL_TYPE_PROVINCE;
    provineMapName.value = provinceName;
    mapUrlQueue.value.push({
      level: type.value,
      adcode,
      value: provinceName,
    });
  } else if (type.value === LEVEL_TYPE_PROVINCE) {
    type.value = LEVEL_TYPE_CITY;
    cityMapName.value = name;
    mapUrlQueue.value.push({
      level: type.value,
      adcode,
      value: name,
    });
  } else {
    return false;
  }
  // if (type.value === LEVEL_TYPE_CITY) {
  //   return false;
  // }
};
const formatProvinceName = (address: string): string => {
  if (`${address}`.includes('省')) {
    return address;
  } else {
    if (address === '北京') {
      return `${address}`;
    } else if (address === '天津' || address === '重庆' || address === '上海') {
      return `${address}市`;
    } else if (address === '广西') return '广西壮族自治区';
    else if (address === '西藏') return '西藏自治区';
    else if (address === '宁夏') return '宁夏回族自治区';
    else if (address === '新疆') return '新疆维吾尔自治区';
    else if (address === '内蒙古') return '内蒙古自治区';
    else return `${address}省`;
  }
};
// eslint-disable-next-line @typescript-eslint/no-unused-vars
const chartResize = (flag: boolean, geo: string): void => {
  setTimeout(() => {
    const rect = mapRef.value.getBoundingClientRect();
    debugger;
    const opt = {
      width: rect.width,
      height: rect.height,
    };
    if (myChart.value) {
      const options = myChart.value.getOption();
      if (flag) {
        options.geo[0].zoom = geo === 'china' ? 1.5 : 1;
      } else {
        options.geo[0].zoom = geo === 'china' ? 1.7 : 1;
      }
      // options.geo[0].left = flag ? '18%' : '20%';
      myChart.value.setOption(options, true);
      myChart.value.resize(opt);
    }
  }, 100);
};
</script>

<style lang="less" module>
.myMap {
  position: relative;
  height: 100%;
  .langed {
    position: absolute;
    left: 20px;
    bottom: 20px;
    font-size: 16px;
    .content {
      display: flex;
      align-items: center;
      cursor: pointer;
      margin-bottom: 18px;
      .circle {
        width: 10px;
        height: 10px;
        border-radius: 50%;
        margin-right: 5px;
      }
    }
  }
  .backMapBtn {
    position: absolute;
    left: 50%;
    transform: translateX(-50%);
    bottom: 20px;
    .backMapLabel {
      display: inline-block;
      line-height: 1;
      white-space: nowrap;
      cursor: pointer;
      color: var(--font-active);
      background-color: var(--inline-menu-active);
      border-color: var(--primary-50);
      text-align: center;
      box-sizing: border-box;
      transition: 0.1s;
      font-weight: 500;
      padding: 12px 20px;
      font-size: 14px;
      border-radius: 4px;
    }
  }
}
</style>
<style lang="less">
.screenAreaBox {
  min-width: 140px;
  max-width: 180px;
}
.screenProjectBox {
  min-width: 140px;
  max-width: 400px;
}
.toolTipTitle {
  font-size: 16px;
  font-weight: bold;
}
.projectTitle {
  white-space: break-spaces;
  line-height: 24px;
}
.toolTipBuild {
  display: flex;
  align-items: self-start;
  margin: 5px 0;
  .labelTip {
    background-color: var(--tag);
    border: 1px solid var(--border);
    width: 85px;
    height: 24px;
    color: var(--font);
    border-radius: 12px;
    display: flex;
    justify-content: center;
    align-items: center;
  }
  .valueTip {
    margin-left: 10px;
  }
  .projectTip {
    .address {
      max-width: 300px;
      white-space: normal;
      word-break: break-all;
    }
  }
}
</style>
